package com.ndp.fb.walle.business.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Sets;
import com.ndp.fb.constant.CommonConstants;
import com.ndp.fb.enums.adresource.ThirdPicReviewStatus;
import com.ndp.fb.model.AdResourceStats;
import com.ndp.fb.model.business.bo.nfs.NfsConfig;
import com.ndp.fb.model.business.vo.stats.AdResourceStatsQueryParam;
import com.ndp.fb.mongo.api.AdGroupStatsMongoService;
import com.ndp.fb.mongo.api.AdResourceStatsMongoService;
import com.ndp.fb.rdb.api.ConnectionObjectRdbService;
import com.ndp.fb.rdb.api.EntrustAccountRdbService;
import com.ndp.fb.rdb.api.UserRdbServices;
import com.ndp.fb.rdb.model.EntrustAccount;
import com.ndp.fb.rdb.model.User;
import com.ndp.fb.redis.api.RedisClient;
import com.ndp.fb.util.DateUtil;
import com.ndp.fb.util.ListUtil;
import com.ndp.fb.walle.business.AdImageService;
import com.ndp.fb.walle.business.BusinessManagerService;
import com.ndp.fb.walle.business.EntrustAccountService;
import com.ndp.fb.walle.model.vo.adresource.AdimageTagParam;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by infi on 2015/1/31.
 */
@Component
public class AdImageServiceImpl implements AdImageService {
    private final Logger logger = LoggerFactory.getLogger(getClass());
    //锁对象
    private final ReentrantLock lock = new ReentrantLock();
    @Reference
    AdResourceStatsMongoService adResourceStatsMongoService;
    @Reference
    AdGroupStatsMongoService adGroupStatsMongoService;
    @Autowired
    private BusinessManagerService businessManagerService;
    @Autowired
    private EntrustAccountService entrustAccountService;
    @Reference
    private UserRdbServices userRdbServices;

    @Reference
    private EntrustAccountRdbService entrustAccountRdbService;

    @Reference
    private ConnectionObjectRdbService connectionObjectRdbService;

    @Autowired
    private RedisClient redisClient;
    @Autowired
    private NfsConfig nfsConfig;

    @Override
    public Map<String, Object> getAdimagesList(AdimageTagParam adimageTagParam, User user) {
        logger.info("infi-test adimageTagParam>>>>>" + JSON.toJSONString(adimageTagParam));
        AdResourceStatsQueryParam adResourceStatsQueryParam = buildBaseAdResourceStatsQueryParam(adimageTagParam, user);
        logger.info("infi-test adResourceStatsQueryParam>>>>>" + JSON.toJSONString(adResourceStatsQueryParam));
        adResourceStatsQueryParam.setPage(adimageTagParam.getCPage());
        adResourceStatsQueryParam.setPageSize(adimageTagParam.getPSize());

        List<Map<String, Integer>> sortList = adimageTagParam.getSortList();
        if (sortList == null || sortList.size() == 0) {
            if (sortList == null) {
                sortList = new ArrayList<>();
            }
            Map<String, Integer> createTime = new HashMap<>();
            createTime.put("createTime", -1);
            sortList.add(createTime);
        }
        adResourceStatsQueryParam.setSortList(sortList);
        adResourceStatsQueryParam.getReturnFields().add("ctr"); //ctr
        adResourceStatsQueryParam.getReturnFields().add("cr"); //cr 转化率
        adResourceStatsQueryParam.getReturnFields().add("cost"); //cost 成本
        adResourceStatsQueryParam.getReturnFields().add("spent"); //流水
        adResourceStatsQueryParam.getReturnFields().add("results"); //下载
        adResourceStatsQueryParam.getReturnFields().add("clicks"); //点击
        adResourceStatsQueryParam.getReturnFields().add("impressions"); //展示
        adResourceStatsQueryParam.getReturnFields().add("uniqueImpressions"); //展示人数

//        }
        logger.debug("查询参数>>>>" + com.alibaba.fastjson.JSON.toJSONString(adResourceStatsQueryParam));
        return adResourceStatsMongoService.groupByImageHash(adResourceStatsQueryParam);
    }

    private AdResourceStatsQueryParam buildBaseAdResourceStatsQueryParam(AdimageTagParam adimageTagParam, User user) {
        AdResourceStatsQueryParam adResourceStatsQueryParam = new AdResourceStatsQueryParam();
        String resourceType = adimageTagParam.getResourceType();
        Map<String, Set<Object>> tags = new HashMap<>();
        if (ListUtil.isNotEmpty(adimageTagParam.getAppNames())) {
            tags.put("application", Sets.<Object>newHashSet(adimageTagParam.getAppNames().iterator()));
        }
        adResourceStatsQueryParam.setResourceType(resourceType);
        adResourceStatsQueryParam.setReturnFields(Sets.newHashSet("mongodbId", "createTime", "height", "isDelete", "litImgURL", "litNfsId", "name", "nfsId", "orgId", "resourceType", "tags", "uploadStatus", "userIdSet", "visitPath", "width", "reviewStatus", "reviewer", "reviewTime", "adReviewFeedback", "totoalPageViews", "numOfPageViews", "peopleNumOfPageViews", "comments", "md5", "imageHash"));
        adResourceStatsQueryParam.setIsDelete(0); //没有删除

        //第三方图片操作
        if (adimageTagParam.isReview()) {
            adResourceStatsQueryParam.setFrom(CommonConstants.IMG_FROM_OUTUI);  //从外部设计师过来的
            adResourceStatsQueryParam.setOrgId(user.getOrgId());
            adResourceStatsQueryParam.setTags(tags);
            return adResourceStatsQueryParam;
        }

        adResourceStatsQueryParam.setOrgId(user.getOrgId());
        // 主要广告 UserIdSet 为空
        if (adimageTagParam.getUserIdSet() != null && adimageTagParam.getUserIdSet().size() > 0) {
            adResourceStatsQueryParam.setUserIdSet(adimageTagParam.getUserIdSet());
        }

        /**
         * 1、如果是外部美宣  则查所有审核状态
         * 2、如果是其他角色  则查所有审核通过的
         */
        List<Long> roleIds = userRdbServices.getRoleByUser(user.getId());
        logger.info("infi--test>>>" + user + ">>>>" + JSON.toJSONString(user));
        logger.info("infi--test>>>" + roleIds + ">>>>" + JSON.toJSONString(roleIds));
        if (ListUtil.isNotEmpty(roleIds) && roleIds.contains(CommonConstants.ROLE_OUTERUIDESIGNER)) {
            logger.debug("AdImageServiceImpl buildBaseAdResourceStatsQueryParam() 当前用户是外部美宣。");
            logger.info("infi--test>>>" + user.getTicket() + ">>>>当前用户是外部美宣。");
        } else {
            adResourceStatsQueryParam.setReviewStatus(ThirdPicReviewStatus.PERSON_REVIEW_PASS.getCode());
            logger.info("infi--test>>>" + user.getTicket() + ">>>>不是外部美宣....。");
        }


//        if (!CommonConstants.RESOURCE_TYPE_CAROUSEL.equals(resourceType)) {
        Set<Long> accountSet = Sets.newHashSet();
        //必须要根据公司查询
        List<EntrustAccount> adAccountListByOrgId = entrustAccountRdbService.findAdAccountListByOrgId(user.getOrgId());
        for (EntrustAccount entrustAccount : adAccountListByOrgId) {
            accountSet.add(entrustAccount.getFbAccountId());
        }
        adResourceStatsQueryParam.setAccountIdSet(accountSet);
//        }

        Integer days = adimageTagParam.getDays();
        if (days == null) {
            days = 7;
        }

        if (days == -1) {
            adResourceStatsQueryParam.setStartDay("2014-01-01");
            adResourceStatsQueryParam.setEndDay(DateUtil.getDate(new Date(), Calendar.DAY_OF_MONTH, 0, DateUtil.LONG_DATE_FORMAT));
        } else {
            adResourceStatsQueryParam.setStartDay(DateUtil.getDate(new Date(), Calendar.DAY_OF_MONTH, 0 - days, DateUtil.LONG_DATE_FORMAT));
            adResourceStatsQueryParam.setEndDay(DateUtil.getDate(new Date(), Calendar.DAY_OF_MONTH, 0, DateUtil.LONG_DATE_FORMAT));
        }

        adResourceStatsQueryParam.setOnlyNew(adimageTagParam.isOnlyNew());

        if (!ListUtil.isEmpty(adimageTagParam.getLanguages())) {
            tags.put("languages", Sets.<Object>newHashSet(adimageTagParam.getLanguages()));
        }
        if(StringUtils.isNoneBlank(adimageTagParam.getGender())){
        	if(StringUtils.trim(adimageTagParam.getGender()).equals("1")){
        		tags.put("gender", Sets.<Object>newHashSet(adimageTagParam.getGender()));
        	}else if(StringUtils.trim(adimageTagParam.getGender()).equals("2")){
        		tags.put("gender", Sets.<Object>newHashSet(adimageTagParam.getGender()));
        	}
        }
        adResourceStatsQueryParam.setTags(tags);

        adResourceStatsQueryParam.setFbConnectionObjectIds(adimageTagParam.getFbConnectionObjectIds());

        adResourceStatsQueryParam.setBreakdowns("all");

        return adResourceStatsQueryParam;
    }

    @Override
    public AdResourceStats getAdImageBymongodId(String mongodId) {
        return adResourceStatsMongoService.findByMongodbId(mongodId);
    }


    @Override
    public List<AdResourceStats> getAdimagesAllListMonByimageBathId(String imageBathId) {
        return adResourceStatsMongoService.AdimagesAllListMonByimageBathId(imageBathId);
    }

    @Override
    public Map<String, Integer> groupByImageHashForActiveAdCount(Set<String> imageHashSet, User user) {
        List<EntrustAccount> adAccountListByOrgId = entrustAccountRdbService.findAdAccountListByOrgId(user.getOrgId());
        Set<Long> accountIdSet = new HashSet<>();
        for (EntrustAccount entrustAccount : adAccountListByOrgId) {
            accountIdSet.add(entrustAccount.getFbAccountId());
        }
        return adGroupStatsMongoService.groupByImageHashForActiveAdCount(imageHashSet, accountIdSet);
    }

    @Override
    public void updatePageView(List<AdResourceStats> adResourceStatses) {
        List<AdResourceStats> resultList = new ArrayList<>();
        for (AdResourceStats adResourceStats : adResourceStatses) {
            Long totalPageViews = adResourceStats.getTotoalPageViews() != null ? adResourceStats.getTotoalPageViews() + 1 : 1;
            adResourceStats.setTotoalPageViews(totalPageViews);
            resultList.add(adResourceStats);
        }
        adResourceStatsMongoService.batchUpdateReviewsTotalOfPageViews(resultList);
    }

    @Override
    public void updateCountPageView(String userId, String mongodId, Long numOfPageViews, Long peopleNumOfPageViews) {
        if (numOfPageViews == null) {
            numOfPageViews = 0l;
        }
        if (peopleNumOfPageViews == null) {
            peopleNumOfPageViews = 0l;
        }
        Object object = redisClient.get(CommonConstants.AD_RESOURCE_USERID_PREFIX + userId + "-" + mongodId);
        if (object == null) {
            peopleNumOfPageViews = peopleNumOfPageViews + 1;
            redisClient.set(CommonConstants.AD_RESOURCE_USERID_PREFIX + userId + "-" + mongodId, "1");
        }
        adResourceStatsMongoService.updateCountPageViews(userId, mongodId, numOfPageViews + 1, peopleNumOfPageViews);
    }

    @Override
    public void deleteAdImages(String userId, List<String> mongodbIds) {
        adResourceStatsMongoService.deleteAdImages(userId, mongodbIds);
    }
}
